package gogsci

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gorilla/mux"
	"github.com/sirupsen/logrus"
	"io/ioutil"
	"net/http"
	"time"
)

var (
	logger = logrus.New()
)

type HttpServer struct {
	*mux.Router

	Queue *Queue
}

func NewHttpServer() *HttpServer {

	h := new(HttpServer)
	h.Router = mux.NewRouter()

	h.HandleFunc("/hook", h.Hook).Methods(http.MethodPost)

	return h
}

func (h *HttpServer) Start(address string) error {
	return http.ListenAndServe(address, h)
}

func (h *HttpServer) Abort(w http.ResponseWriter, err error) {
	w.WriteHeader(http.StatusBadRequest)
	w.Write([]byte(err.Error()))
}

func (h *HttpServer) Hook(w http.ResponseWriter, r *http.Request) {

	body, err := ioutil.ReadAll(r.Body)

	if err != nil {
		logger.WithError(err).Info(`failed to read http request body`)
		h.Abort(w, err)
		return
	}

	sig := hmac.New(sha256.New, []byte(`123456`))
	sig.Write(body)
	sign := hex.EncodeToString(sig.Sum(nil))

	if r.Header.Get("X-Gogs-Signature") != sign {
		h.Abort(w, errors.New(`403 Forbidden`))
		return
	}

	pl := new(PushPayload)
	err = json.Unmarshal(body, pl)

	ioutil.WriteFile(fmt.Sprintf("./tmp/%d.json", time.Now().Unix()), body, 0777)
	if err != nil {
		logger.WithError(err).Info(`failed to parse http request body`)
		h.Abort(w, err)
		return
	}

	h.Queue.Push(pl)

	w.WriteHeader(200)
	w.Write([]byte(`success`))
}
